home *** CD-ROM | disk | FTP | other *** search
- ⓪ IMPLEMENTATION MODULE FPUSupport;⓪ (*$Y+,X+,F-*)⓪ ⓪ (*⓪!* 27.11.90 Routinen laufen auch, wenn Aufrufer schon im Supervisormode ist.⓪!* 29.07.91 keine Privilegsverletzung mehr, wenn im Usermode (hyperCACHE030);⓪!* Sprung in Supervisormode nun korrekt (ging bisher gar nicht?!).⓪!* FSAVE bei externalFPU rettet nun Frame in umgekehrter Reihenfolge,⓪!* so daß es nun endlich korrekt funktioniert.⓪!* 15.02.94 Keine Low-Byte-Zugriffe mehr auf fpstat wg. Mega STE⓪!*⓪!* >> Konzept noch nicht perfekt: Wenn Coroutinen ggf.automatisch den⓪!* FPU-Context switchen sollen, würden noch Low-Level-versionen⓪!* von Save/RestoreContext benötigt. Ggf. "usedFPU", "MaxContextSize"⓪!* und diese Low-Level Routinen in ein Modul "FPUBase" packen.⓪!* Die Low-Level-Routinen f. Runtime können hier nicht rein, weil⓪!* hier Storage importiert wird und das zu zirkul. Importen führt.⓪!*)⓪ ⓪ FROM SYSTEM IMPORT ASSEMBLER, BYTE;⓪ ⓪ FROM Storage IMPORT ALLOCATE, DEALLOCATE;⓪ ⓪ IMPORT MOSGlobals, SFP004;⓪ ⓪ FROM SysInfo IMPORT FPUType, FPU, FPUModel;⓪ ⓪ VAR usedFPU: FPUType; (* zeigt die verwendete FPU an *)⓪$model: CARDINAL;⓪ ⓪ CONST movemSize = 8*12 + 3*4;⓪&contextSize = movemSize + 2 + 2 + 256 + 4;⓪ ⓪ (* Die Größe errechnet sich aus:⓪!* 8 * FPn (je 12 Byte)⓪!* je 4 für FPCR/SR/IAR⓪!* 2 für evtl. nicht-Null-Flag⓪!* 2 für Frame-Word von FSAVE⓪!* interne Daten bei Busy State Frame (256 max. möglich)⓪!* 4 zur Sicherheit *)⓪ ⓪ TYPE FPUContext = POINTER TO ARRAY [1..contextSize] OF BYTE;⓪ ⓪ ⓪ PROCEDURE NewContext (VAR context: FPUContext);⓪"BEGIN⓪$NEW (context);⓪$IF context = NIL THEN⓪&ASSEMBLER⓪(TRAP #6⓪(DC.W MOSGlobals.OutOfMemory⓪&END;⓪$ELSE⓪&ASSEMBLER⓪(; Illegales State Frame erzeugen⓪(MOVE.L context(A6),A1⓪(MOVE.L (A1),A0⓪(MOVE.W #$FFFF,movemSize(A0)⓪&END;⓪$END;⓪"END NewContext;⓪ ⓪ PROCEDURE DisposeContext (VAR context: FPUContext);⓪"BEGIN⓪$DISPOSE (context)⓪"END DisposeContext;⓪ ⓪ (*$L-*)⓪ ⓪ PROCEDURE FPUInit;⓪"BEGIN⓪$ASSEMBLER⓪(CMPI #externalFPU,usedFPU⓪(BNE intern⓪(JMP SFP004.FPUReset⓪$intern:⓪(CMPI #internalFPU,usedFPU⓪(BNE none⓪(FMOVE #$0000F400,FPCR ; s. 'Runtime'⓪$none:⓪$END⓪"END FPUInit;⓪ ⓪ (* wird nicht exportiert, da FPUContext eh nur opaque ist und ein manuelles⓪!* allozieren damit gar nicht möglich ist.⓪ PROCEDURE MaxContextSize (): LONGCARD;⓪!(*⓪"* Liefert die maximal nötige Größe des Context-Puffers in Byte.⓪"* Damit kann der Bereich notfalls auf eine andere Weise reserviert⓪"* werden, statt 'NewContext' zu benutzen.⓪"* Dann sollte der für 'FPUContext' angelegte Pu⓪"*)⓪ PROCEDURE MaxContextSize (): LONGCARD;⓪"BEGIN⓪$ASSEMBLER⓪(MOVE.L #contextSize,(A3)+⓪$END⓪"END MaxContextSize;⓪ *)⓪ ⓪ PROCEDURE AcknowledgeException (context: FPUContext);⓪"BEGIN⓪$ASSEMBLER⓪(; Setze Bit 27 im BIU⓪(MOVE.L -(A3),A1⓪(CMPI #internalFPU,usedFPU⓪(BNE noAckn⓪(LEA movemSize(A1),A1⓪(TST.B (A1)⓪(BEQ noAckn ; kein Ackn bei Null-State⓪(CLR D0⓪(MOVE.B 1(A1),D0⓪(BSET #3,(A1,D0.W)⓪&noAckn⓪$END⓪"END AcknowledgeException;⓪ ⓪ ⓪ CONST A2stat = 0; (* Response word of MC68881 read *)⓪(A2ctrl = 2; (* Control word of MC68881 write *)⓪(A2save = 4; (* Save word of MC68881 read *)⓪(A2restore= 6; (* Restore word of MC68881 r/w *)⓪(A2cmd = 10; (* Command word of MC68881 write *)⓪(A2cond = 14; (* Condition word of MC68881 write *)⓪(A2op = 16; (* Operand long of MC68881 read/write *)⓪(A2regsel= $14; (* register select long read *)⓪ ⓪ PROCEDURE SaveContext (context: FPUContext);⓪"BEGIN⓪$ASSEMBLER⓪(MOVEQ #1,D0⓪(MOVE.L D0,-(A7)⓪(MOVE #$20,-(A7)⓪(TRAP #1 ;Super(1)⓪(MOVEQ #-1,D2⓪(TST D0 ; sind wir schon im Supervisormode ?⓪(BNE supv⓪(⓪(MOVE.W D0,4(A7)⓪(TRAP #1 ;Super(0)⓪(MOVE.L D0,A7 ; SSP wiederherstellen⓪(MOVE #$CFFF,D2⓪&supv⓪(MOVE SR,D1⓪(AND D2,D1⓪(MOVE.W D1,-(A7)⓪(⓪(MOVE.L -(A3),A1⓪(MOVE.L A1,A0⓪(ADDA.W #movemSize,A1⓪(⓪(CMPI #externalFPU,usedFPU⓪(BNE.W intern⓪(⓪(MOVE.L A3,D1⓪(MOVEA.W #$FA40,A2⓪(MOVEA.W #$FA50,A3 ; fpop⓪(⓪ wait MOVE.W A2save(A2),D0⓪(CMPI.W #$300,D0⓪(BCC start ; > $300⓪(CMPI.W #$100,D0⓪(BCS nullstate ; < $100⓪(CMPI.W #$200,D0⓪(BCS wait⓪(; Format Error⓪(CLR.W (A1) ; IDLE-format word sichern⓪(MOVE.L D1,A3⓪(MOVE.W (A7)+,SR⓪(ADDQ.L #6,A7⓪(LINK A5,#0⓪(JSR SFP004.FPUError⓪(UNLK A5⓪(RTS⓪ nullstate:⓪(MOVE.W D0,(A1) ; null-format word sichern⓪(BRA.W endextern⓪ ⓪ start MOVE.W D0,(A1)+ ; format word sichern⓪(; Anzahl der Bytes im Lower Byte -> Anz. der Longs berechnen⓪(ANDI #$FF,D0⓪(ADDA.W D0,A1⓪(LSR #2,D0⓪(SUBQ #1,D0⓪(; während der Datenübertragung des FSAVE keine Interrupts zulassen⓪(MOVE SR,D2⓪(MOVE #$2700,SR⓪ loop MOVE.L (A3),-(A1)⓪(TST.W (A2) ; fpstat wg. Synchr. lesen⓪(DBRA D0,loop⓪(MOVE D2,SR⓪(⓪(; FMOVEM FP0-FP7,(A0)+⓪(TST.W (A2)⓪(MOVE.W #1111000011111111%,A2cmd(A2)⓪(TST.W (A2)⓪(TST.W (A2)⓪(TST.W A2regsel(A2)⓪(TST.W (A2)⓪(MOVEQ #7,D0⓪ again MOVE.L (A3),(A0)+⓪(TST.W (A2) ; fpstat wg. Synchr. lesen⓪(MOVE.L (A3),(A0)+⓪(TST.W (A2) ; fpstat wg. Synchr. lesen⓪(MOVE.L (A3),(A0)+⓪(TST.W (A2) ; fpstat wg. Synchr. lesen⓪(DBRA D0,again⓪(⓪(; FMOVEM FPCR/FPSR/FPIAR,(A0)+⓪(MOVE.W #1011110000000000%,A2cmd(A2) ;$BC00⓪(TST.W (A2)⓪(;TST.W (A2)⓪(;TST.W A2regsel(A2)⓪(;TST.W (A2)⓪(MOVE.L (A3),(A0)+⓪(TST.W (A2) ; fpstat wg. Synchr. lesen⓪(MOVE.L (A3),(A0)+⓪(TST.W (A2) ; fpstat wg. Synchr. lesen⓪(MOVE.L (A3),(A0)+⓪(TST.W (A2) ; fpstat wg. Synchr. lesen⓪$endextern:⓪(MOVE.L D1,A3⓪(BRA none⓪ ⓪$intern:⓪(CMPI #internalFPU,usedFPU⓪(BNE none⓪(FSAVE (A1)⓪(TST.B (A1)⓪(BEQ none⓪(FMOVEM FP0-FP7,-(A1)⓪(FMOVEM FPCR/FPSR/FPIAR,-(A1)⓪$none:⓪(MOVE.W (A7)+,SR⓪(ADDQ.L #6,A7⓪$END⓪"END SaveContext;⓪ ⓪ PROCEDURE RestoreContext (context: FPUContext);⓪"BEGIN⓪$ASSEMBLER⓪(MOVEQ #1,D0⓪(MOVE.L D0,-(A7)⓪(MOVE #$20,-(A7)⓪(TRAP #1 ;Super(1)⓪(MOVEQ #-1,D2⓪(TST D0 ; sind wir schon im Supervisormode ?⓪(BNE supv⓪(⓪(MOVE.W D0,4(A7)⓪(TRAP #1 ;Super(0)⓪(MOVE.L D0,A7 ; SSP wiederherstellen⓪(MOVE #$CFFF,D2⓪&supv⓪(MOVE SR,D1⓪(AND D2,D1⓪(MOVE.W D1,-(A7)⓪(⓪(MOVE.L -(A3),A1⓪(MOVE.L A1,A0⓪(ADDA.W #movemSize,A1⓪(⓪(CMPI #externalFPU,usedFPU⓪(BNE.W intern⓪(⓪(TST.B (A1)⓪(BEQ.W nullstate⓪(⓪(MOVE.L A3,D1⓪(MOVEA.W #$FA40,A2⓪(MOVEA.W #$FA50,A3⓪(⓪(; first reset FPU to be able to transfer the regs⓪(MOVE.W #3,A2ctrl(A2) ; write abort-cmd⓪(⓪(; FMOVEM (A0)+,FP0-FP7⓪(MOVE.W #1101000011111111%,A2cmd(A2)⓪(TST.W (A2)⓪(TST.W (A2)⓪(TST.W A2regsel(A2)⓪(TST.W (A2)⓪(MOVEQ #7,D0⓪ again MOVE.L (A0)+,(A3)⓪(TST.W (A2)⓪(MOVE.L (A0)+,(A3)⓪(TST.W (A2)⓪(MOVE.L (A0)+,(A3)⓪(TST.W (A2)⓪(DBRA D0,again⓪(⓪(; FMOVEM (A0)+,FPCR/FPSR/FPIAR⓪(MOVE.W #1001110000000000%,A2cmd(A2)⓪(TST.W (A2)⓪(;TST.W (A2)⓪(;TST.W A2regsel(A2)⓪(;TST.W (A2)⓪(MOVE.L (A0)+,(A3)⓪(TST.W (A2)⓪(MOVE.L (A0)+,(A3)⓪(TST.W (A2)⓪(MOVE.L (A0)+,(A3)⓪(TST.W (A2)⓪ ⓪(; FRESTORE (A1)⓪(MOVE.W (A1)+,D0⓪(MOVE.W D0,A2restore(A2)⓪(CMP.W A2restore(A2),D0⓪(BEQ start⓪(⓪(MOVE.L D1,A3⓪(⓪(; Format Error⓪ error MOVE.W (A7)+,SR⓪(ADDQ.L #6,A7⓪(LINK A5,#0⓪(JSR SFP004.FPUError⓪(UNLK A5⓪(RTS⓪ ⓪ nullstate:⓪(MOVEA.W #$FA46,A2 ; fprestore⓪(MOVE.W (A1),D0⓪(MOVE.W D0,(A2) ; FRESTORE⓪(CMP.W (A2),D0⓪(BEQ none⓪(BRA error⓪(⓪ start ; Anzahl der Bytes im Lower Byte -> Anz. der Longs berechnen⓪(ANDI #$FF,D0⓪(LSR #2,D0⓪(SUBQ #1,D0⓪(; während der Datenübertragung keine Interrupts zulassen⓪(MOVE SR,D2⓪(MOVE #$2700,SR⓪ loop MOVE.L (A1)+,(A3)⓪(TST.W (A2)⓪(DBRA D0,loop⓪(MOVE D2,SR⓪(MOVE.L D1,A3⓪(BRA none⓪(⓪$intern:⓪(CMPI #internalFPU,usedFPU⓪(BNE none⓪(TST.B (A1)⓪(BEQ null_rst⓪(FMOVEM (A0)+,FPCR/FPSR/FPIAR⓪(FMOVEM (A0)+,FP0-FP7⓪$null_rst:⓪(FRESTORE (A1)⓪$none:⓪(MOVE.W (A7)+,SR⓪(ADDQ.L #6,A7⓪$END⓪"END RestoreContext;⓪ ⓪ BEGIN⓪"usedFPU:= FPU ();⓪$(* egal, ob die vorhandene FPU auch wirklich benutzt wird: wenn hier⓪%* eine der Funktionen aufgerufen wird, ists auf jeden Fall nicht die⓪%* falsche. *)⓪"model:= FPUModel ();⓪ END FPUSupport.⓪ ə
- (* $FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$000001F9$FFEE3A76$00002226$FFEE3A76$00000893$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76Ç$000001F3T.......T.......T.......T.......T.......T.......T.......T.......T.......T.......$00001588$00001625$00001715$00001ACA$00001BC4$00001C48$00001CB5$00001D59$00001FFB$0000165D$00001CED$0000003E$000001F9$000001C0$000001F6$000001D4ÇÇé*)
-